package dataexplorer;

import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.math.*;
import java.util.logging.*;
import javax.swing.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;


public class Animation extends JPanel implements Runnable, MouseListener, MouseMotionListener{

    private Algorithm algorithm;
    private Thread thread = new Thread(this);
    private GUI gui;
    private int firstSelectedDimension = 0;
    private int secondSelectedDimension = 1;
    
    private double minw=0;
    private double minh=0;
    private double maxw=0;
    private double maxh=0;
    private int width;
    private int height;
    
    public Animation(Algorithm algorithm, GUI gui) {
        
        this.algorithm = algorithm;
        this.gui = gui;
        addMouseListener(this);
        addMouseMotionListener(this);
        thread.start();
    }
    
    @Override
    public void paint(Graphics g) {
        super.paint(g);
        Graphics2D g2 = (Graphics2D)g;
        
        List<Element> data = algorithm.getData();
        int dimensions = algorithm.getDimensions();

        if(data!=null){
            
            width = getWidth()-20;
            height = getHeight()-20;
            
            for (int i = 0; i < data.size(); i++) {
                Element element = data.get(i);
                int j=0;
                for (Double f : element.getAttributes()) {
                    if(j == firstSelectedDimension){
                        if(i==0 || f < minw)minw = f;
                        if(i==0 || f > maxw)maxw = f;
                    }
                    if(j == secondSelectedDimension){
                        if(i==0 || f < minh)minh = f;
                        if(i==0 || f > maxh)maxh = f;
                    }
                    j++;
                }
            }

            for (int i = 0; i < data.size(); i++) {
                int j = 0;
                Element element = data.get(i);
                int w=0,h=0;
                for (Double f : element.getAttributes()) {
                    if(j == firstSelectedDimension){
                        w = (int) ((f-minw)*width/(maxw-minw));
                    }
                    if(j == secondSelectedDimension){
                        h = (int) ((f-minh)*height/(maxh-minh));
                    }
                    j++;
                }
                int clazz = element.getClazz();
                Color color = null;

                if(clazz==1){
                    color = Color.RED;
                }
                else if(clazz==2){
                    color = Color.BLUE;
                }
                else if(clazz==3){
                    color = Color.YELLOW;
                }
                else if(clazz==4){
                    color = Color.GREEN;
                } else{
                    color = Color.BLACK;
                }

                boolean draw = true;
                
                if(algorithm.isAnimation()){
                    List<Line> vector = algorithm.getVector();
                    for(int k=0; k<vector.size(); k++){
                        if(k==algorithm.getClicks()/2)break;
                        if(vector.get(k).getDirection() == 0){
                            if(vector.get(k).getValue() >= (element.getAttributes())[vector.get(k).getDimension()]){
                                draw = false;
                            }
                        }
                        if(vector.get(k).getDirection() == 1){
                            if(vector.get(k).getValue() <= (element.getAttributes())[vector.get(k).getDimension()]){
                                draw = false;
                            }
                        }
                    }
                }
                
                if(draw){
                    g2.setColor(color);
                    g2.drawOval(10+w-2,10+h-2,4,4);
                }
            }
            List<Line> vector = algorithm.getVector();
            
            g2.setColor(Color.BLACK);
            if(vector!=null){
                int k = 0;
                for(Line l : vector){
                    g2.setColor(Color.BLACK);
                    int dimension = l.getDimension();
                    int w = getWidth();
                    int h = getHeight();
                    
                    boolean draw = true;

                    if(algorithm.isAnimation()){
                        draw = false;
                        
                        if((algorithm.getClicks()%2==1) && ((k)==(algorithm.getClicks()/2))){
                            draw = true;
                        }
                    }

                    if(draw){
                        if(dimension==0){
                            int value = (int) ((l.getValue()-minw)*width/(maxw-minw));
                            g2.drawLine(10+value, 0, 10+value, h);
                        }
                        if(dimension==1){
                            int value = (int) ((l.getValue()-minh)*height/(maxh-minh));
                            g2.drawLine(0, 10+value, w, 10+value);
                        }
                    }
                    
                    k++;
                }
            }
        }
        
    }

    @Override
    public void run() {
        while(true){
            repaint();
            try {
                Thread.currentThread().sleep(50);
            } catch (InterruptedException ex) {
                Logger.getLogger(Animation.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        if(algorithm.isAnimation()==true){
            algorithm.setClicks(algorithm.getClicks()+1);
            if(algorithm.getClicks()==2*algorithm.getVector().size()+1){
                algorithm.setAnimation(false);
            }
        }
    }

    @Override
    public void mousePressed(MouseEvent e) {
    }

    @Override
    public void mouseReleased(MouseEvent e) {
    }

    @Override
    public void mouseEntered(MouseEvent e) {
    }

    @Override
    public void mouseExited(MouseEvent e) {
    }

    @Override
    public void mouseDragged(MouseEvent e) {
    }

    @Override
    public void mouseMoved(MouseEvent e) {
        
        if(algorithm.getData()==null)return;
        
        JLabel statusBar = gui.getStatusBar();
        int x = e.getX();
        int y = e.getY();
        
        double fx = (x-10)*(maxw-minw)/width + minw;
        double fy = (y-10)*(maxh-minh)/height + minh;
        
        statusBar.setText(fx+", "+fy);
    }

}
